package com.shujia.spark.core

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}

object Demo13Join {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf()
    conf.setMaster("local")
    conf.setAppName("join")

    val sc = new SparkContext(conf)

    val idAndNameRDD: RDD[(String, String)] = sc.parallelize(
      List(
        ("001", "张三"),
        ("002", "李四"),
        ("003", "赵六"),
        ("004", "王五")
      )
    )
    val idAndAgeRDD: RDD[(String, Int)] = sc.parallelize(
      List(
        ("001", 23),
        ("002", 24),
        ("003", 26),
        ("005", 25)
      )
    )

    /**
     * inner join: 内关联,只保留关联成功的数据
     *
     */

    val innerJoinRDD: RDD[(String, (String, Int))] = idAndNameRDD.join(idAndAgeRDD)

    //整理数据
    val innerRDD: RDD[(String, String, Int)] = innerJoinRDD.map {
      case (id: String, (name: String, age: Int)) =>
        (id, name, age)
    }

    innerRDD.foreach(println)


    /**
     * left join : 以左表为基础,如果没关联上,右表补空
     */

    val leftJOinRDD: RDD[(String, (String, Option[Int]))] = idAndNameRDD.leftOuterJoin(idAndAgeRDD)

    //整理数据
    val leftRDD: RDD[(String, String, Int)] = leftJOinRDD.map {
      //关联到的数据处理方式
      case (id: String, (name: String, Some(age))) =>
        (id, name, age)

      //没有关联到的数据处理方式
      case (id: String, (name: String, None)) =>
        (id, name, 0)
    }

    leftRDD.foreach(println)


    /**
     * full join: 保留两个表所有的数据
     *
     * Option: 可选的值，有值：some,没有值：None
     *
     */

    val fullJoinRDD: RDD[(String, (Option[String], Option[Int]))] = idAndNameRDD.fullOuterJoin(idAndAgeRDD)


    //整理数据
    val fullRDD: RDD[(String, String, Int)] = fullJoinRDD.map {
      case (id: String, (Some(name), Some(age))) =>
        (id, name, age)

      case (id: String, (Some(name), None)) =>
        (id, name, 0)

      case (id: String, (None, Some(age))) =>
        (id, "未知", age)
    }

    fullRDD.foreach(println)
  }

}
